package com.laobiao.file_netty_lib.netty.server.handler;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.laobiao.file_netty_lib.content.LoggerUtil;
import com.laobiao.file_netty_lib.exception.FileBaseException;
import com.laobiao.file_netty_lib.netty.server.ServerApplication;
import com.laobiao.file_netty_lib.netty.server.ServerBusiness;
import com.laobiao.file_netty_lib.packet.BasePacket;
import com.laobiao.file_netty_lib.packet.command.ResoultCommand;
import com.laobiao.file_netty_lib.packet.command.upload.FileUploadCommand;
import com.laobiao.file_netty_lib.packet.data.BaseDataPacket;
import com.laobiao.file_netty_lib.util.CheckCodeUtil;
import com.laobiao.file_netty_lib.util.FileUtil;

import io.netty.channel.ChannelHandlerContext;

/**
 * 上传业务信息类
 * @author 38079
 *
 */
public class ServerUploadBusiness extends FileUploadCommand implements ServerBusiness{
	private static final Logger logger=LoggerUtil.getLogger(ServerUploadBusiness.class);
	private RandomAccessFile remoteFileWriter;
	private File remoteFile;
	public ServerUploadBusiness(byte[] commandBytes) {
		super(commandBytes);
		createWirte();
	}
	
	public ServerUploadBusiness(FileUploadCommand uploadCommand) {
		super(uploadCommand.getPacketBytes());
		createWirte();
	}
	
	private void createWirte() {
		String saveFilePath = getRemoteFilePath();
		saveFilePath=saveFilePath.replace("\\", "/");
		if(!saveFilePath.startsWith("/")) {
			saveFilePath="/"+saveFilePath;
		}
		remoteFile=new File(ServerApplication.getLocalBaseDir().getAbsolutePath()+saveFilePath);
		if(!remoteFile.exists()) {
			File p = remoteFile.getParentFile();
			if(!p.exists()) {
				p.mkdirs();
			}
			try {
				remoteFile.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				throw new FileBaseException("创建本地接收文件失败！", e, FileBaseException.ERR_PARAM_WRONG);
			}
		}
		try {
			remoteFileWriter = new RandomAccessFile(remoteFile, "rw");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new FileBaseException("创建本地接收文件失败！", e, FileBaseException.ERR_PARAM_WRONG);
		}
	}
	
	/**
	 * 写入数据
	 * @param data
	 */
	public synchronized void writeBytes(byte[] data) {
		try {
			remoteFileWriter.write(data);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			close();
			throw new FileBaseException("写入数据失败！",e, FileBaseException.ERR_PARAM_WRONG);
		}
	}
	
	public synchronized void close() {
		try {
			remoteFileWriter.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		logger.log(Level.CONFIG,"关闭文件读写流【"+remoteFile.getAbsolutePath()+"】！");
	}

	public File getRemoteFile() {
		return remoteFile;
	}

	@Override
	public void hasPacket(ChannelHandlerContext ctx, BasePacket packet) {

		if(packet instanceof ResoultCommand) {//反馈信息包
			ResoultCommand reCommand=(ResoultCommand)packet;
			if (reCommand.isStatus()) {
				if(reCommand.getCode() == ResoultCommand.ResoultCode.Upload.CLIENT_UPLOAD) {// 客户端文件数据传输完成
					logger.info("收到客户端命令:"+reCommand.getMessage());
					// 关闭文件读写操作
					close();
					//开始校验文件
					File file = getRemoteFile();
					logger.log(Level.CONFIG,"开始校验文件【"+file.getAbsolutePath()+"】");
					if(Arrays.equals(CheckCodeUtil.getCheckCode(file), getCheckCode())){
						logger.log(Level.CONFIG,"文件校验成功");
						ResoultCommand command = new ResoultCommand(ResoultCommand.ResoultCode.Common.SERVER_CHECK,
								"文件【"+file.getAbsolutePath()+"】接收完成！" , true, getBusinessGroup());
						ctx.writeAndFlush(command);
						logger.info("文件【"+file.getAbsolutePath()+"】保存成功！向客户端发送上传成功反馈");
					}else {
						
						FileUtil.deleteFile(getRemoteFile());
						ResoultCommand command = new ResoultCommand(ResoultCommand.ResoultCode.Common.SERVER_CHECK,
								"文件校验失败！" , false, getBusinessGroup());
						ctx.writeAndFlush(command);
						logger.warning("文件【"+file.getAbsolutePath()+"】校验失败，已向客户端发送错误消息！");
					}
				}
				
			} else {
				// 关闭文件读写操作
				close();
				FileUtil.deleteFile(getRemoteFile());
				// 有异常消息
				throw new FileBaseException(reCommand.getMessage(), FileBaseException.ERR_UNPREDICTABLE);
			}
		}else if(packet instanceof BaseDataPacket){//数据包
			BaseDataPacket dataPacket = (BaseDataPacket)packet;
			try {
				writeBytes(dataPacket.getContent());
			} catch (Exception e) {
				// TODO: handle exception
				ResoultCommand command = new ResoultCommand(ResoultCommand.ResoultCode.Common.SERVER_RECEIVE,
						"保存失败。" + e.getMessage(), false, getBusinessGroup());
				try {
					ctx.writeAndFlush(command).sync();
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}finally {
					close();
				}
			} 
		}else {
			logger.log(Level.WARNING, "文件上传不支持的包！"+packet);
		}
		
	}
	
}
